package wallet

import (
	"context"
	"github.com/shopspring/decimal"
	"go.uber.org/zap"
	gamepb "navi-mumbai/app/rpc/game/pb"
	"navi-mumbai/app/rpc/wallet/pb"
	"navi-mumbai/common/ctxdata"
	"navi-mumbai/common/xerr"

	"navi-mumbai/app/api/business/internal/svc"
	"navi-mumbai/app/api/business/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type UserTransferFromGameWalletLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserTransferFromGameWalletLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserTransferFromGameWalletLogic {
	return &UserTransferFromGameWalletLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserTransferFromGameWalletLogic) UserTransferFromGameWallet(req *types.UserTransferFromGWalletReq) (resp *types.UserTransferFromGWalletResp, err error) {
	uid := ctxdata.GetUidFromCtx(l.ctx)
	if uid != req.Uid {
		return nil, xerr.NewGrpcErrCodeMsg(xerr.AuthFail, "no privilege")
	}

	// 查询余额
	var in1 gamepb.GetGameWalletBalanceReq
	in1.Uid = req.Uid
	in1.MoneyType = req.MoneyType
	in1.ProviderId = req.ProviderId
	var rsp1 *gamepb.GetGameWalletBalanceResp
	rsp1, err = l.svcCtx.GameWalletRpc.GetGameWalletBalance(l.ctx, &in1)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	var dReqMoneyAmount decimal.Decimal
	dReqMoneyAmount, err = decimal.NewFromString(req.MoneyAmount)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, err.Error())
	}
	var dRspBalance decimal.Decimal
	dRspBalance, err = decimal.NewFromString(rsp1.Balance)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, err.Error())
	}

	if dRspBalance.Cmp(dReqMoneyAmount) < 0 { // 不足
		return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, "balance not enough")
	}
	if req.MoneyAmount == "0" { // 0代表全部转出
		req.MoneyAmount = dRspBalance.String()
	}

	// 创建转账流水
	var in pb.UserCreateTransferFromGameReq
	in = pb.UserCreateTransferFromGameReq{
		Uid:         req.Uid,
		MoneyType:   req.MoneyType,
		ProviderId:  req.ProviderId,
		MoneyAmount: req.MoneyAmount,
	}
	var rsp *pb.UserCreateTransferFromGameResp
	rsp, err = l.svcCtx.WalletUsersRpc.UserCreateTransferFromGame(l.ctx, &in)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	// 请求G端转账
	var in2 gamepb.UserTransferFromGWalletReq
	in2 = gamepb.UserTransferFromGWalletReq{
		Uid:         req.Uid,
		MoneyType:   req.MoneyType,
		ProviderId:  req.ProviderId,
		FlowNo:      rsp.FlowNo,
		MoneyAmount: req.MoneyAmount,
	}
	var rsp2 *gamepb.UserTransferFromGWalletResp
	rsp2, err = l.svcCtx.GameWalletRpc.UserTransferFromGWallet(l.ctx, &in2)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	// 更新转账流水
	var in3 pb.UpdateTransferFromGameResultReq
	in3 = pb.UpdateTransferFromGameResultReq{
		Uid:            req.Uid,
		FlowNo:         rsp.FlowNo,
		State:          rsp2.State,
		ExternalFlowNo: rsp2.ExternalFlowNo,
		MoneyType:      rsp2.MoneyType,
		NewBalance:     rsp2.NewBalance,
		OldBalance:     rsp2.OldBalance,
		ErrMsg:         rsp2.ErrMsg,
	}
	var rsp3 *pb.UpdateTransferFromGameResultResp
	rsp3, err = l.svcCtx.WalletUsersRpc.UpdateTransferFromGameResult(l.ctx, &in3)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	resp = &types.UserTransferFromGWalletResp{
		MoneyType: rsp3.MoneyType,
		Balance:   rsp3.Balance,
	}
	if rsp2.ErrMsg != "" {
		return nil, xerr.NewGrpcErrCodeMsg(xerr.WalletTransferError, rsp2.ErrMsg)
	}
	return
}
